Release CodeTruss CLI v0.2.55 - #47
Merged
Merged
Conversation
Syncs the 0.2.55 source from the private monorepo. 163 paths compared by blob hash against the monorepo git objects, 0 mismatched, 0 missing. Carries 0.2.54 (the README profile-id build guard, merged but never released) and 0.2.55 (the acceptance test that runs the built dist/cli.cjs over committed fixtures inside this repository). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Syncs the 0.2.55 source from the private monorepo, byte for byte against the monorepo git objects (163 paths compared by blob hash, 0 mismatches, 0 missing).
That digest was not copied into
release-reference.json:pnpm release:artifactwas run against this tree, resolved from this repository's own lockfile, and the rebuilt archivecmps clean against the monorepo's copy, against this repo'slatestpointer, and against the bytes codetruss.com is serving right now. All three digests inrelease-reference.jsonwere re-measured off the files — archive, SBOM, and thedist/cli.cjsextracted from inside the archive — rather than transcribed. The samecmpagainst the published 0.2.53 archive exits 1, so the comparison is capable of failing.The blob-hash comparison was run a second time against the pre-sync tree as a negative control: it reported 8 mismatched paths and 7 missing, and exited 1, so a sync that silently dropped a file would not have passed.
Why this one is urgent
https://codetruss.com/downloads/codetruss-cli-latest.jsonalready advertises 0.2.55, and itsreleaseUrl—.../releases/tag/v0.2.55— currently 404s, because the release does not exist yet. Tagging this merge is what makes the advertised URL resolve.This release supersedes an unreleased one
0.2.54 was merged to the monorepo and never released — no tag, no GitHub release, no Homebrew bump. That has precedent here (0.2.42 and 0.2.47 through 0.2.49 are all merged-but-unreleased, served from the site). It is not retroactively released; its changelog entry rides along in the chain and its change ships inside these bytes. The mirror carries download artifacts only for versions that were actually released, so
public/downloads/codetruss-cli-0.2.54.*is deliberately absent, exactly as 0.2.47 through 0.2.49 are.So this archive carries two changes:
0.2.54 — the README's profile id is now derived, not restated. The 0.2.53 archive contradicted itself:
README.mdsaid receipts identify the 15-passlocal-registry-v4profile whileCHANGELOG.md, packed beside it in the same eight-file tarball, saidlocal-registry-v5.scripts/docs-profile-policy.mjsnow readsLOCAL_ANALYSIS_PROFILE.idfrompackages/cli/src/types.tsand the analyzer count fromANALYZERSinpackages/analyzer-engine/src/registry.ts, andbuild-release.mjsasserts the README agrees with both — before any archive bytes exist, because that script refuses to overwrite an already-written versioned tarball. It runs wherever a release is built, in this repository as well as the monorepo.0.2.55 — the mirror's CI can now fail on a rule. That is the part that matters for this repository specifically, and it gets its own section.
Until now, nine green contexts meant packaging, not behaviour
This repository carries
packages/cli/andpackages/analyzer-engine/'spackage.jsonandsrc. It carries no roottests/, andanalyzer-engineshipssrcwith no test directory to carry. The rule-level SAST suites live in the monorepo —tests/sast-regressions.test.tsagainst the hosted implementation,tests/analyzer-engine-parity.test.tsbinding that to the shipped engine — and neither reaches here. A SAST behaviour regression could pass all nine contexts and the release job. Both 0.2.53 fixes were confirmed by an acceptance check run by hand, and the false positive one of them removed had already shipped.packages/cli/scripts/test-acceptance.mjscloses that. It lives underpackages/cli/, so it syncs here with the rest of the package; it joins the three existing scripts in this package'stestscript; it executes the builtdist/cli.cjs— notsrc/, not the hosted implementation — overscripts/fixtures/acceptance/, and asserts the findings the release must and must not produce. Two fixtures, expected verdicts taken from the committed benchmark adjudication: a drizzlesql`…`tagged template that must not be reported (CWE-89 CRITICAL until 0.2.53), andclient.query(param, …)on a database-shaped receiver that must be reported at HIGH on theclient.queryline (silent until 0.2.53). The benchmark repositories are not cloned.Where it actually runs, measured rather than assumed.
.github/workflows/ci.ymlgates theTeststep onmatrix.node != '20.9.0'. So the acceptance script runs in six of the nine compatibility contexts (Node 22 and 24 on ubuntu, macos, windows) and in the tag-triggered release job, which runspnpm testunconditionally. The three Node 20.9.0 contexts run onlytest-deterministic-package.mjsandtest-release-verifier.mjs, and never reach it. The changelog entry inside this archive says "all nine compatibility contexts"; that sentence is wrong, and it is recorded in the "known wart" section below rather than patched, because these bytes are already served.Verified capable of failing, in both directions, from inside this repository. Reverting the 0.2.53 tagged-template exemption in
packages/analyzer-engine/src/security/rules.tsand rebuilding turns it red withCRITICAL sql-injection at src/db/rpc.ts:11 — SQL injectionwhere none is allowed. Switching the caller-supplied-argument gate to() => falseturns it red withexpected exactly 1 sql-injection finding …, got 0. Restoring each returns it to green, and the 163-path blob comparison was re-run afterwards and still reported 163 identical, so the tree in this PR is not a patched-back approximation.Bundle delta
dist/cli.cjsgoes from 828,029 bytes (0.2.53, and 0.2.54 — identical size) to 828,065 (+36), 2 changed lines out of 296, first difference at byte offset 674,865.That delta is entirely the inlined
package.json: the version string, and the 36 characters of&& node scripts/test-acceptance.mjsappended to thetestscript.git diffbetween the 0.2.53 and 0.2.55 monorepo trees reports no changes at all underpackages/cli/srcorpackages/analyzer-engine/src. No analyzer, rule, or receipt behaviour changes in this release. The archive grows 955,997 → 962,141 bytes becauseCHANGELOG.mdships inside it and gained two entries; the eight-file archive membership is unchanged.The frozen renderers still reproduce
Receipts stay on
local-registry-v5. No frozen digest moved. The pinned block inpackages/cli/test/verify-receipt.test.ts— v1928da3c4…, v2113d62de…, v3f38a8bde…, v4288de3e2…, v56ae337ce…— is byte-identical between the 0.2.53 and 0.2.55 monorepo trees.That test is not decoration: flipping the last hex character of the v4 expected digest makes it fail with
renders 'local-registry-v4' to the exact bytes its signature covers(1 failed, 20 passed), and the file was restored byte-exactly afterwards.No published artifact was modified
git statusunderpublic/downloads/reports nothing outsidecodetruss-cli-0.2.55.*and thelatestpointers, so 0.2.44 through 0.2.53 still carry exactly the bytes they were attested with.packages/cli/CHANGELOG.mdis 104 additions, 0 deletions; the 0.2.53, 0.2.52 and 0.2.51 sections are byte-identical to what is already published (8,359, 4,435 and 4,300 bytes respectively, heading excluded).pnpm-workspace.yaml,.npmrc,pnpm-lock.yaml,package.json(root),README.md,CONTRIBUTING.mdand.github/are unchanged — the sync never writes mirror-owned files.CHANGELOG.mdat the root is regenerated frompackages/cli/CHANGELOG.md. The generator was checked by feeding it the 0.2.53 package changelog and confirming it reproduces the committed 0.2.53 root changelog byte-for-byte; run with a deliberately wrong release version it throws, and with a wrong npm-trail version its outputcmps non-zero, so it is capable of failing. Its npm-trail sentence stays at 0.2.50, becausenpm view @codetruss/cli dist-tagsstill reportslatestas 0.2.50.Checked locally before opening
pnpm install --frozen-lockfileresolves with the lockfile untouched (the only source change topackages/cli/package.jsonis the version string and the appended test script).pnpm validatepasses against this branch: typecheck,release:artifact,pnpm test(35 files, 435 tests, plus the deterministic-package, release-verifier, changelog-policy and new acceptance suites),release:verify, andtest:install. The rebuilt archive reproduced12010c43…exactly, and the acceptance script printed:The release workflow's
awkextraction of the changelog entry was dry-run against the regeneratedCHANGELOG.mdand returns 48 non-empty lines (3,644 bytes), so the release note will not be install-steps-only; the sameawkfor a version with no entry returns 0 bytes, which is the case the workflow refuses to publish.One thing this release gets wrong
The 0.2.55 changelog entry — inside this archive — says the acceptance script "runs in all nine compatibility contexts". It runs in six of nine, for the reason given above:
ci.ymlskipspnpm teston Node 20.9.0. The check is real and the gap it closes is closed on every context that runs the test suite, but the count in the prose is wrong.It is not corrected here. The 0.2.55 archive is already committed to the monorepo, already served by codetruss.com, and already advertised by the live manifest under the digest above; editing it now would mean changing bytes that are already published. It is recorded here and belongs in 0.2.56 — the same way the 0.2.53 README error was left standing and corrected in 0.2.54 rather than rewritten.
🤖 Generated with Claude Code